#include "key.h"

//===初始化8级优化(节省RAM)
#pragma OPTIMIZE(8, speed)
#if LONG__KEY_ENABLE == 1 //长短按键初始化
//===长短按键初始化: key_handle--按键句柄  long_start--长按时间  long_hold--连发时间
//参数: key_handle:按键句柄   key_val:按键键值   long_start:长按开始时间   long_hold:长按保持时间
void LongKeyEvents_Init(LongKey_Handle_Type *data key_handle, uint8_t key_val, uint16_t long_start, uint8_t long_hold)
{
	key_handle->new_key = 0;		 //新的按建状态
	key_handle->old_key = 0;		 //旧的按键状态
	key_handle->long_start_flag = 0; //长按开始标志
	key_handle->key_value = key_val; //按键键值

	if (long_hold)
		key_handle->long_hold_time = long_hold; //长按保持时间
	else
		key_handle->long_hold_time = 200;	  //长按保持时间
	key_handle->comparison_time = long_start; //比较时间
	key_handle->long_start_time = long_start; //长按开始时间
	key_handle->hold_time = 0;				  //按下保持时间

	key_handle->down_cb = NULL;		  //按下回调函数
	key_handle->up_cb = NULL;		  //抬起回调函数
	key_handle->long_start_cb = NULL; //长按开始回调函数
	key_handle->long_hold_cb = NULL;  //长按保持回调函数
}
//===长短按键回调函数
//参数: key_handle:按键句柄   down_cb:按下回调函数   up_cb:抬起回调函数  long_start_cb:长按开始回调函数  long_hold_cb:长按保持回调函数
void LongKeyEvents_Set_CB(LongKey_Handle_Type *data key_handle, void (*down_cb)(void), void (*up_cb)(void), void (*long_start_cb)(void), void (*long_hold_cb)(void))
{
	key_handle->down_cb = down_cb;			   //按下回调函数
	key_handle->up_cb = up_cb;				   //抬起回调函数
	key_handle->long_start_cb = long_start_cb; //长按开始回调函数
	key_handle->long_hold_cb = long_hold_cb;   //长按保持回调函数
}
#endif

#if SHORT_KEY_ENABLE == 1 //短按按键初始化
//===短按按键初始化
//参数: key_handle,按键句柄   key_val,按键键值   down_cb,按下回调函数
void ShortKeyEvents_Init(ShortKey_handle_type *data key_handle, uint8_t key_val, void (*down_cb)(void))
{
	key_handle->new_key = 0;		 //新的按建状态
	key_handle->old_key = 0;		 //旧的按键状态
	key_handle->key_value = key_val; //按键键值

	key_handle->down_cb = down_cb; //按下回调函数
}
#endif

//===按键扫描执行1级优化(否则会死机复位)
#pragma OPTIMIZE(1, speed)
#if LONG__KEY_ENABLE == 1 //长短按键扫描执行
//===参数: key_handle,按键句柄   key_val,输入键值
void LongKeyEvents(LongKey_Handle_Type *data key_handle, uint8_t key_val)
{
	//新的按键状态
	if (key_handle->key_value == key_val)
		key_handle->new_key = 1;
	else
		key_handle->new_key = 0;
	//按下判断
	if (key_handle->old_key != key_handle->new_key)
	{
		key_handle->old_key = key_handle->new_key;
		if (key_handle->new_key) //按下
		{
			if (key_handle->down_cb != NULL)
				key_handle->down_cb();
		}
		else //抬起
		{
			if ((key_handle->long_start_flag == 0) && (key_handle->up_cb != NULL))
				key_handle->up_cb();
		}
	}
	//长按判断
	if (key_handle->new_key)
	{
		key_handle->hold_time++;
		if (key_handle->hold_time >= key_handle->comparison_time)
		{
			//长按开始
			if (key_handle->hold_time == key_handle->long_start_time)
			{
				key_handle->long_start_flag = 1;
				if (key_handle->long_start_cb != NULL)
					key_handle->long_start_cb();
			}
			//长按保持
			else
			{
				if (key_handle->long_hold_cb != NULL)
					key_handle->long_hold_cb();
			}
			key_handle->comparison_time += key_handle->long_hold_time;
			//小于代表已经溢出,溢出处理
			if (key_handle->comparison_time < key_handle->hold_time)
			{
				key_handle->comparison_time = key_handle->long_start_time + key_handle->long_hold_time;
				key_handle->hold_time = key_handle->long_start_time;
			}
		}
	}
	else
	{
		key_handle->comparison_time = key_handle->long_start_time; //恢复
		key_handle->hold_time = 0;								   //复位保持计数
		key_handle->long_start_flag = 0;						   //复位长按开始标记
	}
}
#endif

#if SHORT_KEY_ENABLE == 1 //短按按键扫描执行
//===参数: key_handle,按键句柄   key_val,输入键值
void ShortKeyEvents(ShortKey_handle_type *data key_handle, uint8_t key_val)
{
	if (key_handle->key_value == key_val)
		key_handle->new_key = 1;
	else
		key_handle->new_key = 0;
	//===按下判断
	if (key_handle->old_key != key_handle->new_key)
	{
		key_handle->old_key = key_handle->new_key;
		if ((key_handle->new_key) && (key_handle->down_cb != NULL))
		{
			key_handle->down_cb();
		}
	}
}
#endif
